﻿package com.rbac.system.service.impl;

import com.rbac.system.common.Result;
import com.rbac.system.entity.*;
import com.rbac.system.mapper.*;
import com.rbac.system.service.AdminService;
import com.rbac.system.service.MenuPermissionMappingService;
import com.rbac.system.service.PermissionDependencyService;
import com.rbac.system.service.PermissionSyncService;
import com.rbac.system.util.PasswordUtil;
import com.rbac.system.vo.MenuVO;
import com.rbac.system.vo.UserWithRoleVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class AdminServiceImpl implements AdminService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private RoleMapper roleMapper;
    
    @Autowired
    private MenuMapper menuMapper;
    
    @Autowired
    private UserRoleMapper userRoleMapper;
    
    @Autowired
    private RoleMenuMapper roleMenuMapper;
    
    @Autowired
    private PasswordUtil passwordUtil;

    @Autowired
    private PermissionDependencyService permissionDependencyService;

    @Autowired
    private MenuPermissionMappingService menuPermissionMappingService;

    @Autowired
    private PermissionSyncService permissionSyncService;
    
    @Override
    public Result<List<UserWithRoleVO>> getAllUsers() {
        try {
            List<User> users = userMapper.selectByStatus(1);
            
            List<UserWithRoleVO> userWithRoleVOs = users.stream().map(user -> {
                UserWithRoleVO userVO = new UserWithRoleVO();
                userVO.setId(user.getId());
                userVO.setUsername(user.getUsername());
                userVO.setNickname(user.getNickname());
                userVO.setEmail(user.getEmail());
                userVO.setPhone(user.getPhone());
                userVO.setStatus(user.getStatus());
                userVO.setCreateTime(user.getCreateTime());
                userVO.setUpdateTime(user.getUpdateTime());
                
                // 获取用户角色信息
                List<UserRole> userRoles = userRoleMapper.selectByUserId(user.getId());
                
                List<String> roleNames = new ArrayList<>();
                List<Long> roleIds = new ArrayList<>();
                
                for (UserRole userRole : userRoles) {
                    Role role = roleMapper.selectById(userRole.getRoleId());
                    if (role != null) {
                        roleNames.add(role.getRoleName());
                        roleIds.add(role.getId());
                    }
                }
                
                userVO.setRoleNames(roleNames);
                userVO.setRoleIds(roleIds);
                
                return userVO;
            }).collect(Collectors.toList());
            
            return Result.success(userWithRoleVOs);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<Void> addUser(User user) {
        try {
            // 检查用户名是否已存在
            User existUser = userMapper.selectByUsername(user.getUsername());
            if (existUser != null) {
                return Result.error("用户名已存在");
            }
            
            // 密码加密
            user.setPassword(passwordUtil.encode(user.getPassword()));
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            user.setStatus(1);
            user.setDeleted(0);
            
            userMapper.insert(user);
            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<Void> updateUser(Long id, User user) {
        try {
            // 检查用户是否存在
            User existUser = userMapper.selectById(id);
            if (existUser == null) {
                return Result.error("用户不存在");
            }
            
            // 检查用户名是否被其他用户使用
            User duplicateUser = userMapper.selectByUsernameExcludeId(user.getUsername(), id);
            if (duplicateUser != null) {
                return Result.error("用户名已被其他用户使用");
            }
            
            // 更新用户信息
            user.setId(id);
            user.setUpdateTime(LocalDateTime.now());
            
            // 如果密码不为空，则更新密码
            if (user.getPassword() != null && !user.getPassword().trim().isEmpty()) {
                user.setPassword(passwordUtil.encode(user.getPassword()));
            } else {
                // 保持原密码
                user.setPassword(existUser.getPassword());
            }
            
            userMapper.updateById(user);
            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<Void> deleteUser(Long id) {
        try {
            // 检查用户是否存在
            User existUser = userMapper.selectById(id);
            if (existUser == null) {
                return Result.error("用户不存在");
            }
            
            // 软删除：设置状态为0
            existUser.setStatus(0);
            existUser.setUpdateTime(LocalDateTime.now());
            userMapper.updateById(existUser);
            
            // 删除用户角色关联
            userRoleMapper.deleteByUserId(id);
            
            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<User> getUserById(Long id) {
        try {
            User user = userMapper.selectById(id);
            if (user == null) {
                return Result.error("用户不存在");
            }
            
            // 清空密码字段
            user.setPassword(null);
            return Result.success(user);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<List<Long>> getUserRoles(Long userId) {
        try {
            List<UserRole> userRoles = userRoleMapper.selectByUserId(userId);
            List<Long> roleIds = userRoles.stream()
                    .map(UserRole::getRoleId)
                    .collect(Collectors.toList());
            return Result.success(roleIds);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> assignRole(Long userId, Long roleId) {
        try {
            // 检查用户是否存在
            User user = userMapper.selectById(userId);
            if (user == null) {
                return Result.error("用户不存在");
            }
            
            // 检查角色是否存在
            Role role = roleMapper.selectById(roleId);
            if (role == null) {
                return Result.error("角色不存在");
            }
            
            // 获取用户当前的所有角色
            List<UserRole> existUserRoles = userRoleMapper.selectByUserId(userId);
            
            // 检查用户是否已经拥有该角色
            boolean hasRole = existUserRoles.stream().anyMatch(ur -> ur.getRoleId().equals(roleId));
            if (hasRole) {
                return Result.error("用户已拥有该角色");
            }
            
    
            
            // 先删除用户的所有旧角色（软删除）
            if (!existUserRoles.isEmpty()) {
                for (UserRole existUserRole : existUserRoles) {
                    existUserRole.setDeleted(1);
                    userRoleMapper.updateById(existUserRole);
                }
            }
            
            // 分配新角色
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            userRole.setCreateTime(LocalDateTime.now());
            userRole.setDeleted(0);
            userRoleMapper.insert(userRole);
            
            // 角色分配成功
            
            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    

    
    @Override
    public Result<List<Role>> getAllRoles() {
        try {
            // 获取所有角色（包括启用和禁用的），但排除已删除的
            List<Role> roles = roleMapper.selectList(new Role());
            return Result.success(roles);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<Void> addRole(Role role) {
        try {
            // 检查角色名是否已存在
            Role existRole = roleMapper.selectByRoleName(role.getRoleName());
            if (existRole != null) {
                return Result.error("角色名已存在");
            }
            
            // 检查角色代码是否已存在
            Role existRoleCode = roleMapper.selectByRoleCode(role.getRoleCode());
            if (existRoleCode != null) {
                return Result.error("角色代码已存在");
            }
            
            role.setCreateTime(LocalDateTime.now());
            role.setUpdateTime(LocalDateTime.now());
            role.setStatus(1);
            role.setDeleted(0);
            
            roleMapper.insert(role);
            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<Void> updateRole(Long id, Role role) {
        try {
            // 检查角色是否存在
            Role existRole = roleMapper.selectById(id);
            if (existRole == null) {
                return Result.error("角色不存在");
            }
            
            // 检查角色名是否被其他角色使用
            Role duplicateRoleName = roleMapper.selectByRoleNameExcludeId(role.getRoleName(), id);
            if (duplicateRoleName != null) {
                return Result.error("角色名已被其他角色使用");
            }
            
            // 检查角色代码是否被其他角色使用
            Role duplicateRoleCode = roleMapper.selectByRoleCodeExcludeId(role.getRoleCode(), id);
            if (duplicateRoleCode != null) {
                return Result.error("角色代码已被其他角色使用");
            }
            
            // 更新角色信息
            role.setId(id);
            role.setUpdateTime(LocalDateTime.now());
            
            roleMapper.updateById(role);
            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<Void> deleteRole(Long id) {
        try {
            // 检查角色是否存在
            Role existRole = roleMapper.selectById(id);
            if (existRole == null) {
                return Result.error("角色不存在");
            }
            
            // 检查是否有用户使用该角色
            List<UserRole> userRoles = userRoleMapper.selectByRoleId(id);
            if (!userRoles.isEmpty()) {
                return Result.error("该角色正在被用户使用，无法删除");
            }
            
            // 软删除：设置状态为0
            existRole.setStatus(0);
            existRole.setUpdateTime(LocalDateTime.now());
            roleMapper.updateById(existRole);
            
            // 删除角色菜单关联
            roleMenuMapper.deleteByRoleId(id);
            
            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<Role> getRoleById(Long id) {
        try {
            Role role = roleMapper.selectById(id);
            if (role == null) {
                return Result.error("角色不存在");
            }
            return Result.success(role);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<List<MenuVO>> getAllMenus() {
        try {
            // 获取所有启用的菜单和按钮权限
            List<Menu> menus = menuMapper.selectByTypeAndStatus(null, 1);
            List<MenuVO> menuVOs = menus.stream().map(menu -> {
                MenuVO menuVO = new MenuVO();
                menuVO.setId(menu.getId());
                menuVO.setMenuName(menu.getMenuName());
                menuVO.setMenuCode(menu.getMenuCode());
                menuVO.setParentId(menu.getParentId());
                menuVO.setMenuType(menu.getMenuType());
                menuVO.setPath(menu.getPath());
                menuVO.setComponent(menu.getComponent());
                menuVO.setIcon(menu.getIcon());
                menuVO.setSort(menu.getSort());
                return menuVO;
            }).collect(Collectors.toList());
            
            // 构建菜单树
            List<MenuVO> menuTree = buildMenuTree(menuVOs, 0L);
            return Result.success(menuTree);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<List<Long>> getRoleMenus(Long roleId) {
        try {
            List<RoleMenu> roleMenus = roleMenuMapper.selectByRoleId(roleId);
            List<Long> menuIds = roleMenus.stream()
                    .map(RoleMenu::getMenuId)
                    .collect(Collectors.toList());
            return Result.success(menuIds);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> assignMenu(Long roleId, List<Long> menuIds) {
        try {
            // 检查角色是否存在
            Role role = roleMapper.selectById(roleId);
            if (role == null) {
                return Result.error("角色不存在");
            }

            // 删除原有的角色菜单关联
            roleMenuMapper.deleteByRoleId(roleId);

            // 添加新的角色菜单关联
            if (menuIds != null && !menuIds.isEmpty()) {
                // 解析菜单依赖，自动包含父级菜单
                Set<Long> allMenuIds = permissionDependencyService.resolveMenuDependencies(menuIds);

                // 分配菜单
                for (Long menuId : allMenuIds) {
                    RoleMenu roleMenu = new RoleMenu();
                    roleMenu.setRoleId(roleId);
                    roleMenu.setMenuId(menuId);
                    roleMenu.setCreateTime(LocalDateTime.now());
                    roleMenu.setDeleted(0);
                    roleMenuMapper.insert(roleMenu);
                }

                // 使用权限同步服务自动分配菜单对应的权限
                int syncedPermissions = permissionSyncService.syncPermissionsForMenus(roleId, new ArrayList<>(allMenuIds));

                int addedMenuCount = allMenuIds.size() - menuIds.size();
                if (addedMenuCount > 0 || syncedPermissions > 0) {
                    System.out.println("分配菜单成功：");
                    if (addedMenuCount > 0) {
                        System.out.println("  - 已自动包含 " + addedMenuCount + " 个父级菜单");
                    }
                    if (syncedPermissions > 0) {
                        System.out.println("  - 已自动分配 " + syncedPermissions + " 个对应权限");
                    }
                }
            }

            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    

    
    @Override
    public Result<List<Role>> getUserRoleDetails(Long userId) {
        try {
            List<UserRole> userRoles = userRoleMapper.selectByUserId(userId);
            List<Role> roles = userRoles.stream()
                    .map(userRole -> roleMapper.selectById(userRole.getRoleId()))
                    .filter(role -> role != null)
                    .collect(Collectors.toList());
            return Result.success(roles);
        } catch (Exception e) {
            return Result.error("获取用户角色失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> assignRolesToUser(Long userId, List<Long> roleIds) {
        try {
            // 检查用户是否存在
            User user = userMapper.selectById(userId);
            if (user == null) {
                return Result.error("用户不存在");
            }
            
            // 删除原有角色关联
            userRoleMapper.deleteByUserId(userId);
            
            // 添加新的角色关联
            if (roleIds != null && !roleIds.isEmpty()) {
                for (Long roleId : roleIds) {
                    UserRole userRole = new UserRole();
                    userRole.setUserId(userId);
                    userRole.setRoleId(roleId);
                    userRole.setCreateTime(LocalDateTime.now());
                    userRole.setDeleted(0);
                    userRoleMapper.insert(userRole);
                }
            }
            
            return Result.success();
        } catch (Exception e) {
            return Result.error("分配角色失败：" + e.getMessage());
        }
    }

    /**
     * 构建菜单树
     */
    private List<MenuVO> buildMenuTree(List<MenuVO> menus, Long parentId) {
        return menus.stream()
                .filter(menu -> {
                    if (parentId == null) {
                        return menu.getParentId() == null || menu.getParentId() == 0;
                    } else {
                        return parentId.equals(menu.getParentId());
                    }
                })
                .map(menu -> {
                    menu.setChildren(buildMenuTree(menus, menu.getId()));
                    return menu;
                })
                .collect(Collectors.toList());
    }

} 

